/**
 * Created by no1 on 2015/7/24.
 */
'use strict';
let DD = require('./daoLoader');
let F = require('../function');
let Base = require('./Base');
let util = require("util");
let categoryDao = new DD.mongoDB.CategoryDao();
let categoryRedisDao = new DD.redisDB.CategoryDao();


/**
 * 内部调用方法 获取类别树结构
 * @param type
 * @returns {Array}
 */
var getCateTree = function*(type) {
  let retRedis = yield categoryRedisDao.find('category:tree');

  //判断redis中是否存在数据,没有则添加到redis
  if (!retRedis.data) {
    let Que = {'status': 1, 'type': 3}
      , arrDel = ['_id', '__v', '__t', 'createdAt', 'ts', 'updateAt', 'status']
      , opt = {};
    for (let one of arrDel) opt[one] = 0;
    let retMongo = yield categoryDao.getByQuery(Que, opt);
    if (retMongo.error == 1) return [];
    //组装类别结构
    let retass = yield assembleCateData(retMongo.data);
    //保存到redis
    let ret = yield categoryRedisDao.save('category:tree', JSON.stringify(retass));
    if (ret.error == 1) return [];

    retRedis = yield categoryRedisDao.find('category:tree');
  }
  return JSON.parse(retRedis.data);
}
/**
 * 组装类别
 * @param data
 * @returns {Array}
 */
var assembleCateData = function*(data) {
  data = JSON.parse(JSON.stringify(data));
  let levelA = {}, levelB = {}, tmpData = [], tmpData2 = [];
  for (let i in data) {
    let node = data[i];
    if (0 == node.pCode) levelA[node.code] = node;
    else tmpData.push(node);
  }
  for (let i in tmpData) {
    let node = tmpData[i];
    let pCode = node.pCode;
    if (levelA[pCode]) {
      levelA[pCode].nextCate || (levelA[pCode].nextCate = []);
      levelA[pCode].nextCate.push(node);
      levelB[node.code] = node;
    }
    else tmpData2.push(node);
  }
  for (let i in tmpData2) {
    let node = tmpData2[i];
    let pCode = node.pCode;
    if (levelB[pCode]) {
      levelB[pCode].nextCate || (levelB[pCode].nextCate = []);
      levelB[pCode].nextCate.push(node);
    }
  }
  let retData = [];
  for (let i in levelA) retData.push(levelA[i]);
  return retData;
}


function CategoryDispatcher(data) {
  data = data || {};
  data.dao = data.dao || categoryDao;
  data.esDao = data.esDao || {};
  data.redisDao = data.redisDao || {};
  data.modelName = data.modelName || 'category';
  data.modelType = data.modelType || 'mongo';
  this.data = data;
  Base.call(this, this.data);
};
util.inherits(CategoryDispatcher, Base);

/**
 *@todo 添加
 *@param  {Object}  IDArray  所商家的id集合
 *@ret    {Object}  商家的列表
 */
CategoryDispatcher.prototype.add = function*(fields) {
  let parameters = {}
    , arr = ['name', 'code', 'pCode', 'level', 'type', 'status', 'threadCategory']
  for (let one of arr) parameters[one] = fields[one];

  if (!(parameters.code || parameters.name)) return F.returnData(1, '请添加code或name', 3);
  parameters.pCode = parameters.pCode || 0;
  parameters.type = parameters.type || 0;
  parameters.status = parameters.status || 1;
  parameters.level = 1;
  //如果有父类查询父类
  if (parameters.pCode != 0) {
    if (parameters.code == parameters.pCode) return F.returnData(1, 'code与pCode不可相同', 3);
    let ret = yield this.dao.getOneByQuery({code: parameters.pCode});
    if (!ret.data) return F.returnData(1, '没有找到pCode.');
    if (ret.data.level >= 3) return F.returnData(1, '目前只支持到3三级');
    parameters.level = (ret.data.level || 1) + 1;
  }
  //保存
  let ret = yield this.dao.findAndSave({code: parameters.code}, parameters, 'code');
  if (ret.error == 1) return F.returnData(1, ret.msg, 3);
  let json = JSON.parse(JSON.stringify(ret.data));
  let retData = F.dataFilter(json, ['_id', '__v', 'updateAt', 'createdAt', 'status']);

  return F.returnData(0, ret.msg, retData);
};

/**
 * @todo 更新
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
CategoryDispatcher.prototype.update = function*(fields) {


  let update = fields.updata;
  delete update.code;
  delete update.level;
  if (update.pCode) {//判断类别的level等级
    if (update.pCode != 0) {
      if (update.pCode == fields.code) return F.returnData(1, 'code与pCode不可以一样');
      let ret = yield this.dao.getOneByQuery({code: update.pCode});
      if (!ret.data) return F.returnData(1, '没有找到pCode.')
      update.level = ret.data.level + 1;
    } else {
      update.level = 0;
    }
  }

  var ret = yield this.dao.findAndUpdate({code: fields.code}, update);
  if (ret.error == 1) return F.returnData(0, ret.msg, ret.data);
  return F.returnData(0, ret.msg, ret.data);
}

/**
 * @todo 获取列表
 * @param fields
 * @returns {{error, msg, data}|{error, msg}}
 */
CategoryDispatcher.prototype.list = function*(fields) {
  let parameters = {}, opt = {}, retData = {}, ret = {}
    , arrDel = ['_id', '__v', '__t', 'createdAt', 'ts', 'updateAt'];

  //一层查询
  if (fields.act == 1) {
    for (let one of arrDel) opt[one] = 0;
    if (!!fields.type) parameters.type = fields.type;
    if (fields.status != null) parameters.status = fields.status;
    parameters.pCode = fields.pCode || 0;

    ret = yield this.dao.getByQuery(parameters, opt);
    if (ret.error == 1) return F.returnData(1, ret.msg, ret.data);
    retData = ret.data;
  }
  //多层查询
  else if (fields.act == 2) {
    let tpye = fields.type;
    if (tpye != 3) return F.returnData(1, '该功能目前只支持商品类别');
    retData = yield getCateTree(tpye);
  }
  //id集合
  else if (fields.act == 3) {
    fields.codes || (fields.codes = []);
    parameters.code = {$in: fields.codes}
    for (let one of arrDel) opt[one] = 0;
    ret = yield this.dao.getByQuery(parameters, opt);
    if (ret.error == 1) return F.returnData(1, ret.msg, ret.data);
    retData = ret.data;
  }

  return F.returnData(0, ret.msg, retData);
}

/**
 *@todo 根据code集合搜索列表
 *@param  {Object}  IDArray  所商家的id集合
 *@ret    {Object}  商家的列表
 */
CategoryDispatcher.prototype.getBycodeArray = function*(IDArray) {
  let ret = yield this.dao.getByQuery({code: {$in: IDArray}});
  if (ret.error == 1) return F.returnData(1, ret.msg)
  return F.returnData(0, ret.msg, ret.data);
};

/**
 @ todo 服务类型拼接
 @catCode 传入的类别code
 @返回的date
 @category={
 code:1,
 name:xx,
 pCode:2
 }
 */
CategoryDispatcher.prototype.jointServices = function*(paramSers) {
  let services = [];//临时存放类别参数的数组
  for (let one of paramSers) {
    if (one.code) {
      let onecat = {};//单个类别的参数
      let catRet = yield this.dao.getOneByQuery({code: one.code, type: 4});//查找对应的类别
      if (catRet.error == 1) return F.returnData(1, catRet.msg, 3);
      onecat.code = one.code;
      onecat.name = catRet.data.name || '';
      services.push(onecat);
    } else return F.returnData(0, '必须有code', 3)
  }
  return services;
};
CategoryDispatcher.prototype.jointSerByCodes = function*(codes) {
  let arrDel = ['__v', '__t', 'createdAt', 'updateAt']
    , opt = {}
    , categories = [];
  for (let one of arrDel) opt[one] = 0;
  let ret = yield this.dao.getByQuery({code: {$in: codes}, status: 1, type: 4}, opt);
  if (ret.error == 1) return F.returnData(1, ret.msg);
  for (let one of ret.data) {
    let cate = {};
    cate.code = one.code;
    cate.name = one.name || '';
    //添加新的shop到shops
    categories.push(cate);
  }
  return F.returnData(0, 'ok', categories);
}
/**
 * @ todo 类别拼接
 * @param paramCates
 * @returns {*}
 */
CategoryDispatcher.prototype.jointCategories = function*(paramCates) {
  let categories = [];//临时存放类别参数的数组
  for (let one of paramCates) {
    if (one.code) {
      let onecat = {};//单个类别的参数
      let catRet = yield this.dao.getOneByQuery({code: one.code});//查找对应的类别
      if (catRet.error == 1) return F.returnData(1, catRet.msg);
      onecat.code = one.code;
      onecat.name = catRet.data.name || '';
      onecat.pCode = catRet.data.pCode || 0;//父级标签
      categories.push(onecat);
    } else return F.returnData(0, '必须有code', 3)
  }
  return categories;
};
/**
 * todo 根据codes拼接
 * @param paramCates
 */
CategoryDispatcher.prototype.jointCateByCodes = function*(cates) {
  let arrDel = ['__v', '__t', 'createdAt', 'updateAt']
    , opt = {}
    , categories = [];
  for (let one of arrDel) opt[one] = 0;
  let ret = yield this.dao.getByQuery({code: {$in: cates}, status: 1, type: 3}, opt);
  if (ret.error == 1) return F.returnData(1, ret.msg);
  for (let one of ret.data) {
    let cate = {};
    cate.code = one.code;
    cate.name = one.name || '';
    cate.pCode = one.pCode || 0;//父级标签
    //添加新的shop到shops
    categories.push(cate);
  }
  return F.returnData(0, 'ok', categories);
}

/**
 * 内部调用
 * @param Que
 * @returns {{error, msg, data}|{error, msg}}
 */
CategoryDispatcher.prototype.findByDis = function*(Que) {
  let arrDel = ['code', 'name', 'type', 'status', 'pCode']
    , opt = {};
  for (let one of arrDel) opt[one] = 1;
  let ret = yield  this.dao.getByQuery(Que, opt);
  let json = JSON.parse(JSON.stringify({data: ret.data}));
  let retData = F.dataFilter(json, ['_id']);
  if (ret.error == 1) return F.returnData(1, ret.msg, retData.data);
  return F.returnData(0, ret.msg, retData.data);
};

module.exports = CategoryDispatcher;
